import React, { useCallback, useMemo, useState, useContext } from 'react';
import { Button, Modal, Table, Form, Typography, Tooltip, message } from 'antd';
import { uniqueId, size, trim, omit, isEqual, zipObject, fill, defaults, last } from 'lodash';
import classNames from 'classnames';
import { useCustomCompareEffect } from 'react-use';

import BizIcon from '@/components/BizIcon';
import If from '@/components/If';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';
import { useDynamicList } from '@/hooks';
import { BaseSettingContext } from '@/pages/SalaryManage/constant/BaseSettingContext';

import SignSelect, { LE, LT } from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/components/SignSelect';
import { NumberSettingInput } from '@/pages/SalaryManage/components/NumberSettingInput';
import style from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/CPFSetting/index.less';
import util from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/CPFSetting/util';
import numUtil from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/skillsDevelopmentTax/util';

import EditItem from './editItem';

const TipItem = ({ messageArray, children }) => (
    <div className={style.tipItem}>
        <div className={style.content}>{children}</div>
        <div className={style.tip}>{messageArray.join(',')}</div>
    </div>
);

const tableColumns = (form, { onDelete, onlyUpdate, onEditCompanyShare, onUpdate, validateField, scale }) => {
    const rel = [
        {
            title: '雇员该自然月薪资总额',
            dataIndex: 'vvTotalRange',
            render(text, record, index) {
                const errorFieldMap = record?.vvValidateInfo?.errorFieldMap || {};
                const messageArray = record?.vvValidateInfo?.tipMap?.vvTotalRange || [];
                return (
                    <TipItem messageArray={messageArray}>
                        <div className={style.rangeBox}>
                            <NumberSettingInput
                                prefix="$"
                                className={classNames(style.start, {
                                    [style.error]: !!errorFieldMap?.twStartAmt
                                })}
                                placeholder="最小值"
                                style={{ width: 100 }}
                                nonNegative
                                value={record.twStartAmt}
                                onChange={value => {
                                    onUpdate('twStartAmt', value, index, record);
                                }}
                                onBlur={util.delayExecute(() =>
                                    validateField(['twStartAmt', 'twEndAmt'], index, 'vvTotalRange')
                                )}
                            />

                            <SignSelect
                                value={record.twStartAmtSign}
                                onChange={value => {
                                    onUpdate('twStartAmtSign', value, index, record);
                                }}
                            />

                            <span>薪资总额</span>

                            <SignSelect
                                value={record.twEndAmtSign}
                                onChange={value => {
                                    onUpdate('twEndAmtSign', value, index, record);
                                }}
                            />

                            <NumberSettingInput
                                value={record.twEndAmt}
                                prefix="$"
                                className={classNames(style.end, {
                                    [style.error]: !!errorFieldMap?.twEndAmt
                                })}
                                placeholder="最大值"
                                style={{ width: 100 }}
                                nonNegative
                                onChange={value => {
                                    onUpdate('twEndAmt', value, index, record);
                                }}
                                onBlur={util.delayExecute(() =>
                                    validateField(['twStartAmt', 'twEndAmt'], index, 'vvTotalRange')
                                )}
                            />
                        </div>
                    </TipItem>
                );
            }
        },

        {
            title: '雇主扣除额',
            dataIndex: 'sdlRate',
            render(text, record) {
                const { sdlAmt, sdlRate, sdlPayStyle } = record || {};
                const sdlAmtTxt = typeof sdlAmt === 'number' ? `$${numUtil.getNumberFormat(sdlAmt, false, scale)}` : null;
                const sdlRateTxt = typeof sdlRate === 'number' ? `月薪资总额 ${numUtil.getNumberFormat(sdlRate, true, scale)}%` : null;
                const str = sdlPayStyle === 2 ? sdlRateTxt : sdlAmtTxt;
                const messageArray = record?.vvValidateInfo?.tipMap?.sdlRate || [];
                return (
                    <TipItem messageArray={messageArray}>
                        {str ? <span>{str}</span> : <Typography.Text type="secondary">点击编辑</Typography.Text>}
                    </TipItem>
                );
            },
            onCell(record, rowIndex) {
                return {
                    style: {
                        cursor: 'pointer'
                    },
                    onClick: () => {
                        onEditCompanyShare(record, rowIndex);
                    }
                };
            }
        }
    ];

    if (!onlyUpdate) {
        rel.push({
            title: '操作',
            width: 50,
            dataIndex: '',
            render(text, record, index) {
                return (
                    <Tooltip title="删除">
                        <Button
                            className={salaryStyle.operateIcon}
                            onClick={() => {
                                Modal.confirm({
                                    title: '确定删除',
                                    content: '确定要删除吗',
                                    okText: '确定',
                                    cancelText: '取消',
                                    onOk() {
                                        onDelete(record, index);
                                    }
                                });
                            }}
                        >
                            <BizIcon type="DeleteIcon" />
                        </Button>
                    </Tooltip>
                );
            }
        });
    }
    return rel;
};

const validateRow = (row, validateFields) => {
    const tipMap = {};
    const errorFieldMap = {};

    const addMessageTip = (warnField, warnMessage) => {
        if (!tipMap[warnField]) {
            tipMap[warnField] = [];
        }
        tipMap[warnField].push(warnMessage);
    };
    // 1. 单个字段校验
    // <editor-fold desc="单个字段校验">
    if (util.needValidate(['sdlAmt', 'sdlRate'], validateFields)) {
        if ((!trim(row.sdlAmt) && row.sdlPayStyle === 1) || (!trim(row.sdlRate) && row.sdlPayStyle === 2)) {
            addMessageTip('sdlRate', '请填写');
        }
    }

    if (util.needValidate(['twStartAmt', 'twEndAmt'], validateFields) && !trim(row.twStartAmt) && !trim(row.twEndAmt)) {
        errorFieldMap.twStartAmt = true;
        errorFieldMap.twEndAmt = true;
        addMessageTip('vvTotalRange', '雇员该自然月薪资总额起始值与结束值至少填一个!');
    }

    if (
        util.needValidate(['twStartAmt', 'twEndAmt'], validateFields) &&
        trim(row.twStartAmt) &&
        trim(row.twEndAmt) &&
        row.twStartAmt > row.twEndAmt
    ) {
        errorFieldMap.twStartAmt = true;
        errorFieldMap.twEndAmt = true;
        addMessageTip('vvTotalRange', '雇员该自然月薪资总额起始值不能大于结束值!');
    }

    return { tipMap, errorFieldMap };
};
/**
 * 添加校验信息
 * @param {Array | Object} rows
 * @param {Array | Object } validateFields
 * @returns {(*&{validateInfo: {errorField, message}})|*}
 */
const addValidateInfo = (rows, validateFields) =>
    util.mapRows(rows, row => ({ vvValidateInfo: validateRow(row, validateFields) }));

const EditDetailModal = ({ title, visible, onCancel, onOk, form, onlyUpdate, editData, sdlId, editRowId }) => {
    const { list: dataSource, resetList: resetDataSource, push, replace, remove } = useDynamicList([]);
    const [shareModalVisible, setShareModalVisible] = useState(false);
    const [editModelData] = useState({
        row: {},
        index: 0
    });
    const {
        baseSetting: { scale = 2 }
    } = useContext(BaseSettingContext);
    const handleAdd = () => {
        const newItem = {
            vvId: uniqueId('id'),
            twStartAmt: null,
            sdlPayStyle: 1,
            sdlId,
            twStartAmtSign: LT.value,
            twEndAmt: null,
            twEndAmtSign: LE.value,
            sdlRate: null,
            sdlAmt: null
        };

        if (size(dataSource) === 0) {
            push(newItem);
            return;
        }
        // 取出最后一条数据
        const { sdlPayStyle, twEndAmt, twEndAmtSign, sdlRate, sdlAmt } = last(dataSource);
        Object.assign(newItem, {
            sdlId,
            sdlPayStyle,
            sdlRate,
            sdlAmt
        });

        if (trim(twEndAmt)) {
            Object.assign(newItem, { twStartAmt: twEndAmt, twEndAmt: null });
            Object.assign(newItem, {
                twStartAmtSign: LT.value === twEndAmtSign ? LE.value : LT.value,
                twEndAmtSign
            });
        }
        push(newItem);
    };


    const validateField = useCallback(
        (fields, index, tipRangeField, row) => {
            const record = row || dataSource[index];
            const oldValidateInfo = record.vvValidateInfo || { tipMap: {}, errorFieldMap: {} };
            const defaultValidateInfo = {
                errorFieldMap: zipObject(fields, fill(Array(fields), false)),
                tipMap: tipRangeField ? { [tipRangeField]: [] } : zipObject(fields, fill(Array(fields), []))
            };
            const validateInfo = validateRow(record, fields);
            const newValidateInfo = {
                errorFieldMap: defaults(validateInfo.errorFieldMap, defaultValidateInfo.errorFieldMap),
                tipMap: defaults(validateInfo.tipMap, defaultValidateInfo.tipMap)
            };
            const mergeValidateInfo = {
                tipMap: { ...oldValidateInfo.tipMap, ...newValidateInfo.tipMap },
                errorFieldMap: { ...oldValidateInfo.errorFieldMap, ...newValidateInfo.errorFieldMap }
            };
            const newRecord = { ...record, vvValidateInfo: mergeValidateInfo };
            replace(index, newRecord);
        },
        [dataSource, replace]
    );
    const onEditCompanyShare = useCallback((record, rowIndex) => {
        editModelData.row = record;
        editModelData.index = rowIndex;
        setShareModalVisible(true);
    }, []);
    const onUpdate = useCallback(
        (field, fieldValue, index) => {
            const newRecord = { ...dataSource[index], [field]: fieldValue };
            replace(index, newRecord);
        },
        [dataSource, replace]
    );
    const onDelete = useCallback(
        (record, index) => {
            remove(index);
        },
        [remove]
    );

    const handleOk = () => {
        const newDataSource = addValidateInfo(dataSource);
        resetDataSource(newDataSource);

        if (size(newDataSource) === 0) {
            message.error('请添加数据');
            return;
        }

        const hasError = data => size(Object.keys((data.vvValidateInfo || { tipMap: {} }).tipMap || {})) > 0;
        // 如果校验不通过
        if (newDataSource.find(data => hasError(data))) {
            message.error('请正确填写信息');
            return;
        }

        const postData = newDataSource.map(item => ({
            id: editData.id,
            ...omit(item, ['vvId', 'vvValidateInfo', 'vvShowMax'])
        }));
        onOk(onlyUpdate ? postData[0] : postData);
    };

    useCustomCompareEffect(
        () => {
            if (editRowId) {
                resetDataSource([{ vvId: uniqueId('id'), ...editData }]);
            } else {
                handleAdd()
            }
        },
        [editRowId, resetDataSource],
        ([, ...prevCpfDetailId], [, ...nextCpfDetailId]) => isEqual(prevCpfDetailId, nextCpfDetailId)
    );

    const columns = useMemo(
        () => tableColumns(form, { onDelete, onlyUpdate, onEditCompanyShare, onUpdate, validateField, scale }),
        [form, onDelete, onlyUpdate, onEditCompanyShare, onUpdate, validateField]
    );
    return (
        <>
            <Modal
                title={title}
                visible={visible}
                width="700px"
                onCancel={onCancel}
                onOk={handleOk}
                style={{ top: 50 }}
                destroyOnClose
            >
                <Form layout="inline" className={style.detailModal}>
                    <Table
                        rowKey="vvId"
                        columns={columns}
                        dataSource={dataSource}
                        pagination={false}
                        scroll={{ x: 'max-content' }}
                        bordered
                        className={style.detailTable}
                    />
                    {!onlyUpdate ? (
                        <Button type="dashed" block onClick={handleAdd} style={{ marginTop: 16, marginBottom: 32 }}>
                            + 添加
                        </Button>
                    ) : null}
                </Form>
            </Modal>
            <If condition={shareModalVisible}>
                <EditItem
                    visible={shareModalVisible}
                    title="雇主扣除额"
                    model={editModelData.row}
                    onCancel={() => setShareModalVisible(false)}
                    onOk={e => {
                        replace(editModelData.index, e);
                        setShareModalVisible(false);
                    }}
                />
            </If>
        </>
    );
};
EditDetailModal.defaultProps = {
    title: '新增',
    onCancel: () => { },
    onOk: () => { },
    onlyUpdate: false,
    editData: {},
    sdlId: ''
};

export default Form.create({})(EditDetailModal);
